package edu.zju.udms.dnavigator.entities.mongodb;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

import com.mongodb.CommandResult;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.Mongo;

import edu.zju.udms.dnavigator.core.entity.Entity;
import edu.zju.udms.dnavigator.core.entity.ExtractorField;
import edu.zju.udms.dnavigator.core.entity.FieldTypeEnum;
import edu.zju.udms.dnavigator.core.entity.Record;
import edu.zju.udms.dnavigator.core.entity.Relation;
import edu.zju.udms.dnavigator.core.extract.Extractor;
import edu.zju.udms.dnavigator.core.utils.Tuple3;

public class MongoDBExtractor extends Extractor{
	@ExtractorField(FieldTypeEnum.WEB_USE)
	public static final String SOURCE="MongoDB";
	
	private static final Logger logger=Logger.getLogger(MongoDBExtractor.class);
	
	@ExtractorField(FieldTypeEnum.SAVE)
	@ExtractorField(FieldTypeEnum.SHOW_IN_PANEL)
	@ExtractorField(FieldTypeEnum.WEB_USE)
	public String host;
	
	@ExtractorField(FieldTypeEnum.SAVE)
	@ExtractorField(FieldTypeEnum.SHOW_IN_PANEL)
	@ExtractorField(FieldTypeEnum.WEB_USE)
	public String port="27017";
	
	@ExtractorField(FieldTypeEnum.SAVE)
	@ExtractorField(FieldTypeEnum.WEB_USE)
	public String username;
	
	@ExtractorField(FieldTypeEnum.SAVE)
	@ExtractorField(FieldTypeEnum.WEB_USE)
	public String password;
	
	@ExtractorField(FieldTypeEnum.SAVE)
	@ExtractorField(FieldTypeEnum.SHOW_IN_PANEL)
	@ExtractorField(FieldTypeEnum.WEB_USE)
	public String database;
	
	@SuppressWarnings("rawtypes")
	@Override
	public Tuple3<List<Entity>, List<Relation>, List<Record>> extract() throws Exception {
		logger.info(String.format("MongoDB extractor start,host %s ,port %s,database %s",
				host, port, database));
		List<Entity> res = new ArrayList<>();
		String hostName = host+":"+port;
		Mongo mongo = new Mongo(host, Integer.parseInt(port));
		DB db = mongo.getDB(database);
		if(db!=null){
			db.authenticate(username, password.toCharArray());
			//database
			CommandResult status = db.getStats();
			Map map = status.toMap();
			MongoDBDatabase dbEntity = new MongoDBDatabase(hostName,(String)map.get("db"), (int)map.get("collections"), (int)map.get("objects"), (((Number)map.get("dataSize")).longValue()/1024/1024)+"MB");
			res.add(dbEntity);
			
			//collections
			Set<String> collectionNames = db.getCollectionNames();
			for(String cName:collectionNames){
				logger.info("extract collection "+ cName);
				DBCollection coll = db.getCollection(cName);
				CommandResult stemp = coll.getStats();
				Map cInfo = stemp.toMap();
				res.add(new MongoDBCollection(hostName,(String)cInfo.get("ns"),dbEntity.getId().toString(),(int)cInfo.get("count"), (((Number)cInfo.get("size")).longValue()/1024/1024)+"MB"));
			}
		}
		mongo.close();
		logger.info("MongoDB extractor finish,extract entities size: "+res.size());
		return new Tuple3<List<Entity>, List<Relation>, List<Record>>(res, new ArrayList<>(), new ArrayList<>());
	}
	
	public static void main(String[] args) throws Exception {
		BasicConfigurator.configure();
		MongoDBExtractor m=new MongoDBExtractor();
		m.host="10.21.31.72";
		m.database="medical";
		m.username="udms";
		m.password="udms1234";
//		List<Entity> es = m.extract();
//		for(Entity e:es){
//			logger.debug(e);
//		}
	}

	@Override
	public String getSource() {
		return SOURCE;
	}
}
